﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.ComplexEventProcessing;
using Microsoft.ComplexEventProcessing.Adapters;
using Microsoft.Samples.SmartGrid.AMI.MeterEventType;
using System.Threading;
using Microsoft.Samples.SmartGrid.AMI.WcfOutputAdapter.btsFilteredMeterEventService;
using System.ServiceModel;

namespace Microsoft.Samples.SmartGrid.AMI.WcfOutputAdapter
{
    class WcfOutputPointAdapter : PointOutputAdapter
    {
        private WcfOutputAdapterConfig config;
        private CepEventType eventType;
        private MeterEventServiceClient client = null;

        public WcfOutputPointAdapter(WcfOutputAdapterConfig config, CepEventType type)
        {
            this.config = config;
            this.eventType = type;

            BasicHttpBinding basicBinding = new BasicHttpBinding();
            
            EndpointAddress endpointAddress = new EndpointAddress(config.endpointAddress);

            this.client = new MeterEventServiceClient(basicBinding, endpointAddress);

            this.client.Open();

        }
        public override void Resume()
        {
            new Thread(this.ConsumeEvents).Start();
        }

        public override void Start()
        {
            new Thread(this.ConsumeEvents).Start();
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                this.client.Close();
            }
            base.Dispose(disposing);
        }

        public void ConsumeEvents()
        {
            PointEvent currentEvent = default(PointEvent);

            while (true)
            {
                if (AdapterState.Stopping == AdapterState)
                {
                    Stopped();
                    return;
                }

                if (DequeueOperationResult.Empty == Dequeue(out currentEvent))
                {
                    Ready();
                    return;
                }

                if (currentEvent.EventKind == EventKind.Insert)
                {
                    //Create Message
                    MeterEvent msg = CreateServiceMessage(currentEvent);

                    //Send Message to service
                    client.SubmitFilteredMeterEvent(msg);
                }

                ReleaseEvent(ref currentEvent);
            }
        }

        public MeterEvent CreateServiceMessage(PointEvent currentEvent)
        {
            MeterEventMeterInfo inf = new MeterEventMeterInfo()
            {
                HeadendID = currentEvent.GetField(4).ToString(),
                Number = currentEvent.GetField(5).ToString(),
                VendorID = currentEvent.GetField(6).ToString()
            };

            MeterEventMeterData dt = new MeterEventMeterData()
            {
                CurrentReading=currentEvent.GetField<double>(0),
                Temp=currentEvent.GetField<double>(1)
            };


            MeterEvent msg = new MeterEvent() 
                { 
                    Code="Outage", //Probably shouldn't code this in the adapter but let the bus set
                    TimeStamp=currentEvent.GetField<DateTime>(2),
                    EventType = currentEvent.GetField(3).ToString(),
                    MeterInfo=inf,
                    MeterData=dt
                };
             
            return msg;
        }
    }
}
